package za.ac.wits.was.courses.allocations;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import za.ac.wits.was.courses.Course;
import za.ac.wits.was.user.model.AcademicStaff;

/**
 *
 * @author Salman Noor : School of Electrical and Information Engineering
 * @Copyright: Wits University 2013 - All Rights Reserved
 * @email: salmannoor74415@gmail.com
 * @License: BSD License (http://www.linfo.org/bsdlicense.html)
 */
@Service
@Transactional
public class CourseAllocationsService {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public List<CourseAllocations> getActiveCourseAllocations(Long discipline_id) {
        Session sess = this.sessionFactory.openSession();
        List<CourseAllocations> ca = sess.createQuery("from CourseAllocations ca where ca.course.discipline.discipline_id = :disciplineID AND pending = FALSE AND approved = TRUE").setParameter("disciplineID", discipline_id).list();
        if (ca == null) {
            return new ArrayList();
        }
        for (CourseAllocations c : ca) {
            c.getAcademic_staff_member();
            c.getCourse();
        }
        sess.flush();
        sess.close();
        return ca;
    }

    public List<Course> getCourses(String username) {
        Session sess = this.sessionFactory.openSession();
        AcademicStaff academicStaffUser = (AcademicStaff) sess.createQuery("from was_user where username = :username ").setParameter("username", username).uniqueResult();
        Set<Course> academicCourses = academicStaffUser.getDiscipline().getCourses();
        List<Course> coursesList = new ArrayList<Course>();
        coursesList.addAll(academicCourses);
        sess.flush();
        sess.close();

        return coursesList;
    }

    public List<CourseAllocations> getPendingCourseAllocations() {
        Session sess = this.sessionFactory.openSession();
        List<CourseAllocations> pendingAllocations = sess.createQuery("from CourseAllocations where pending = TRUE").list();
        if (pendingAllocations == null) {
            return new ArrayList<CourseAllocations>();
        }
        for (CourseAllocations ca : pendingAllocations) {
            ca.getAcademic_staff_member();
            ca.getCourse();
        }
        sess.flush();
        sess.close();
        return pendingAllocations;
    }
    
    public CourseAllocations createApprovedNewCourseAllocations(Long courseID, Long academic_staff_id, Calendar startDate) {
        Session sess = this.sessionFactory.openSession();
        AcademicStaff academicStaffUser = (AcademicStaff) sess.get(AcademicStaff.class, academic_staff_id);
        Course courseToTeach = (Course) sess.get(Course.class, courseID);
        CourseAllocations newCourseAllocation = new CourseAllocations();
        newCourseAllocation.setAcademic_staff_member(academicStaffUser);
        newCourseAllocation.setApproved(true);
        newCourseAllocation.setCourse(courseToTeach);
        newCourseAllocation.setPending(false);
        newCourseAllocation.setStart_date(startDate.getTime());
        sess.save(newCourseAllocation);
        sess.flush();
        sess.close();
        return newCourseAllocation;
    }

    public CourseAllocations createNewCourseAllocations(Long courseID, String username, Calendar startDate) {
        Session sess = this.sessionFactory.openSession();
        AcademicStaff academicStaffUser = (AcademicStaff) sess.createQuery("from was_user where username = :username ").setParameter("username", username).uniqueResult();
        Course courseToTeach = (Course) sess.get(Course.class, courseID);
        CourseAllocations newCourseAllocation = new CourseAllocations();
        newCourseAllocation.setAcademic_staff_member(academicStaffUser);
        newCourseAllocation.setApproved(false);
        newCourseAllocation.setCourse(courseToTeach);
        newCourseAllocation.setPending(true);
        newCourseAllocation.setStart_date(startDate.getTime());
        sess.save(newCourseAllocation);
        sess.flush();
        sess.close();
        return newCourseAllocation;
    }

    public CourseAllocations approveCourseAllocation(Long course_allocation_id) {
        Session sess = this.sessionFactory.openSession();
        CourseAllocations thePendingCourse = (CourseAllocations) sess.get(CourseAllocations.class, course_allocation_id);
        thePendingCourse.setApproved(Boolean.TRUE);
        thePendingCourse.setPending(Boolean.FALSE);
        sess.saveOrUpdate(thePendingCourse);
        sess.flush();
        sess.close();
        return thePendingCourse;
    }

    public CourseAllocations declineCourseAllocation(Long course_allocation_id) {
        Session sess = this.sessionFactory.openSession();
        CourseAllocations thePendingCourse = (CourseAllocations) sess.get(CourseAllocations.class, course_allocation_id);
        thePendingCourse.setApproved(Boolean.FALSE);
        thePendingCourse.setPending(Boolean.FALSE);
        sess.saveOrUpdate(thePendingCourse);
        sess.flush();
        sess.close();
        return thePendingCourse;
    }
}
